package com.hm.myapplication;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.widget.NestedScrollView;
import androidx.recyclerview.widget.RecyclerView;



public class NestedScrollLayout extends NestedScrollView {
    private View topView;
    private ViewGroup contentView;
    private static final String TAG = "NestedScrollLayout";

    public NestedScrollLayout(Context context) {
        this(context, null);
        init();
    }

    public NestedScrollLayout(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
        init();
    }

    public NestedScrollLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr, 0);
        init();
    }

    public NestedScrollLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private FlingHelper mFlingHelper;

    int totalDy = 0;
    /**
     * 用于判断RecyclerView是否在fling
     */
    boolean isStartFling = false;
    /**
     * 记录当前滑动的y轴加速度
     */
    private int velocityY = 0;

    /**
     * 初始化方法，设置滚动帮助器和滚动监听器
     */
    private void init() {
        // 初始化FlingHelper实例，用于辅助处理fling手势
        mFlingHelper = new FlingHelper(getContext());

        // 设置滚动监听器，以处理滚动事件
        setOnScrollChangeListener(new View.OnScrollChangeListener() {
            @Override
            public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
                // 记录当前滚动位置
                Log.i(TAG, "............."+scrollY);

                // 如果是开始fling状态，重置总偏移量并更新状态
                if (isStartFling) {
                    totalDy = 0;
                    isStartFling = false;
                }
                // 当滚动到顶部时
                if (scrollY == 0) {
                    Log.i(TAG, "TOP SCROLL");
                   // refreshLayout.setEnabled(true);
                }
                // 当滚动到底部时
                if (scrollY == (getChildAt(0).getMeasuredHeight() - v.getMeasuredHeight())) {
                    Log.i(TAG, "BOTTOM SCROLL");
                    // 尝试分发子视图的fling动作
                    dispatchChildFling();
                }
                // 在RecyclerView fling情况下，记录当前RecyclerView在y轴的偏移
                totalDy += scrollY - oldScrollY;
            }
        });
    }

    /**
     * 处理子视图的滑动操作
     * 本方法旨在计算并执行基于当前滑动速度的子视图滑动距离
     * 仅当当前滑动速度不为零时，才进行滑动距离的计算和处理
     */
    private void dispatchChildFling() {
        // 检查是否有滑动速度
        if (velocityY != 0) {
            // 使用速度计算滑动距离
            Double splineFlingDistance = mFlingHelper.getSplineFlingDistance(velocityY);
            // 判断计算得到的滑动距离是否大于已记录的滑动距离
            if (splineFlingDistance > totalDy) {
                // 如果是，根据滑动距离差更新滑动速度，并执行滑动操作
                childFling(mFlingHelper.getVelocityByDistance(splineFlingDistance - Double.valueOf(totalDy)));
            }
        }
        // 重置滑动距离和速度，为下一次滑动操作做准备
        totalDy = 0;
        velocityY = 0;
    }

    /**
     * 触发子RecyclerView的滑动动画
     * <p>
     * 本方法旨在处理子RecyclerView的滑动逻辑当子RecyclerView存在时，为其启动一个滑动动画
     * 这通常用于响应用户的手指滑动动作或其他触发滑动的事件
     *
     * @param velY 滑动的垂直速度，表示滑动的快慢程度
     */
    private void childFling(int velY) {
        // 获取当前视图中的子RecyclerView
        RecyclerView childRecyclerView = getChildRecyclerView(contentView);
        // 如果子RecyclerView存在，则为其启动一个滑动动画
        if (childRecyclerView != null) {
            childRecyclerView.fling(0, velY);
        }
    }

    @Override
    public void fling(int velocityY) {
        super.fling(velocityY);
        if (velocityY <= 0) {
            this.velocityY = 0;
        } else {
            isStartFling = true;
            this.velocityY = velocityY;
        }
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        topView = ((ViewGroup) getChildAt(0)).getChildAt(0);
        contentView = (ViewGroup) ((ViewGroup) getChildAt(0)).getChildAt(1);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // 调用父类的onMeasure方法，确保基本的测量工作完成
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        // 获取contentView的布局参数
        ViewGroup.LayoutParams lp = contentView.getLayoutParams();

        // 将contentView的高度设置为当前ViewGroup的测量高度
        // 这是为了确保contentView能够填充整个布局，防止在父容器滚动后出现空白区域
        lp.height = getMeasuredHeight();

        // 应用修改后的布局参数到contentView
        contentView.setLayoutParams(lp);
    }




    @Override
    public void onNestedPreScroll(@NonNull View target, int dx, int dy, @NonNull int[] consumed, int type) {
        Log.i("NestedScrollLayout", getScrollY()+"::onNestedPreScroll::"+topView.getMeasuredHeight());
        // 向上滑动。若当前topview可见，需要将topview滑动至不可见
        boolean hideTop = dy > 0 && getScrollY() < topView.getMeasuredHeight();
        if (hideTop) {
            scrollBy(0, dy);
            consumed[1] = dy;
        }
    }

    /**
     * 递归查找嵌套在ViewGroup中的RecyclerView实例
     *
     * @param viewGroup 要搜索的ViewGroup对象，可以是布局或包含其他视图的任何容器
     * @return 如果找到符合条件的RecyclerView实例，则返回该实例；否则返回null
     */
    private RecyclerView getChildRecyclerView(ViewGroup viewGroup) {
        // 遍历ViewGroup中的所有子视图
        for (int i = 0; i < viewGroup.getChildCount(); i++) {
            View view = viewGroup.getChildAt(i);
            // 检查当前子视图是否为RecyclerView实例且具体类型为NestedLogRecyclerView
            if (view instanceof RecyclerView && view.getClass() == NestedLogRecyclerView.class) {
                // 如果找到符合条件的RecyclerView，返回当前视图
                return (RecyclerView) viewGroup.getChildAt(i);
            } else if (viewGroup.getChildAt(i) instanceof ViewGroup) {
                // 如果当前子视图是一个ViewGroup实例，递归调用以搜索其内部的RecyclerView
                ViewGroup childRecyclerView = getChildRecyclerView((ViewGroup) viewGroup.getChildAt(i));
                if (childRecyclerView instanceof RecyclerView) {
                    // 如果在子ViewGroup中找到RecyclerView，返回找到的RecyclerView实例
                    return (RecyclerView) childRecyclerView;
                }
            }
            // 继续处理下一个子视图
            continue;
        }
        // 如果没有找到任何符合条件的RecyclerView实例，返回null
        return null;
    }
}



